<template>
  <el-scrollbar height="100vh">
    <div class="container">
      <el-affix :offset="1">
        <h1 class="title">图层组 LayerGroup</h1>
      </el-affix>
      <div id="map" class="map-x" ref="mapBox"></div>
      <el-row :gutter="20" style="margin-top: 20px;">
        <el-col :span="3">
          <span>OSM图层</span><br/>
          <el-checkbox v-model="visible1" label="是否可见" size="large" @change="changeCheckBox('visible1', 'osm')" /><br/>
          <span>透明度</span>
          <el-slider v-model="visible1Opacity" size="small" :format-tooltip="formatTooltip" @change="changeOpacity('visible1Opacity', 'osm')" />
        </el-col>
      </el-row>
      <el-divider />
      <el-row :gutter="20">
        <el-col :span="3">
          <span>天地图路网图层</span>
          <el-checkbox v-model="visible2" label="是否可见" size="large" @change="changeCheckBox('visible2', 'tdroad')" /><br/>
          <span>透明度</span>
          <el-slider v-model="visible2Opacity" size="small" :format-tooltip="formatTooltip" @change="changeOpacity('visible2Opacity', 'tdroad')" />
        </el-col>
      </el-row>
      <el-divider />
      <el-row :gutter="20">
        <el-col :span="3">
          <span>天地图文字标注图层</span>
          <el-checkbox v-model="visible3" label="是否可见" size="large" @change="changeCheckBox('visible3', 'tdtxt')"/><br/>
          <span>透明度</span>
          <el-slider v-model="visible3Opacity" size="small" :format-tooltip="formatTooltip" @change="changeOpacity('visible3Opacity', 'tdtxt')" />
        </el-col>
      </el-row>
      <dl>
        <dt>图层组 LayerGroup</dt>
        <dd>可以设置多个图层，通过source.getLayers()方法遍历图层，找到所需要的图层进行操作。</dd>
        <dd>setVisible可以设置图层显示或隐藏</dd>
        <dd>setOpacity可是设置图层的透明度，接收一个数值类型的参数</dd>
      </dl>
      <div class="codestyle"><Code /></div>
    </div>
  </el-scrollbar>
</template>
<script>
import { toRefs, reactive, ref, onMounted } from 'vue-demi'
import Code from './code.vue'
import 'ol/ol.css'
import { Map, View } from 'ol'
import OSM from 'ol/source/OSM'
import Tile from 'ol/layer/Tile'
import XYZ from 'ol/source/XYZ'
import { Group as LayerGroup, Tile as TileLayer } from 'ol/layer'
export default {
  setup () {
    const state = reactive({
      map: ref(null),
      mapBox: ref(null),
      visible1: true,
      visible1Opacity: 100,
      visible2: true,
      visible2Opacity: 100,
      visible3: true,
      visible3Opacity: 100,
      formatTooltip: (val) => {
        return val / 100
      }
    })

    const init = () => {
      state.map = new Map({
        target: state.mapBox,
        layers: [
          new TileLayer({
            name: 'osm',
            source: new OSM()
          }),
          new LayerGroup({
            layers: [
              new Tile({
                name: 'tdroad',
                source: new XYZ({
                  url: 'http://t4.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=ab47b4591ab6e07e0530606eca973edd'
                })
              }),
              new Tile({
                name: 'tdtxt',
                source: new XYZ({
                  url: 'http://t3.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=ab47b4591ab6e07e0530606eca973edd'
                })
              })
            ]
          })
        ],
        view: new View({
          // 地图视图
          projection: 'EPSG:4326', // 坐标系，有EPSG:4326和EPSG:3857
          center: [116.41400, 39.91500], // 北京坐标
          zoom: 7 // 地图缩放级别（打开页面时默认级别）
        })
      })
    }

    // 显示/隐藏图层
    // setVisible可以设置图层显示或隐藏
    const changeCheckBox = (target, name) => {
      const layers = find(state.map, name)
      layers.setVisible(state[target])
    }

    // 查找图层
    const find = (source, name) => {
      const s = source.getLayers()
      for (let i = 0; i < s.getLength(); i++) { // 遍历所有图层
        if (s.item(i).get('name') === name) { // 根据图层名，查找并返回查找到的图层
          return s.item(i)
        }
        if (s.item(i) instanceof LayerGroup) { // 递归
          return find(s.item(i), name)
        }
      }
    }

    // 修改图层透明度
    // setOpacity可是设置图层的透明度，接收一个数值类型的参数
    const changeOpacity = (target, name) => {
      const layers = find(state.map, name)
      layers.setOpacity(parseFloat(state[target] / 100))
    }

    onMounted(() => {
      init()
    })

    return {
      init,
      find,
      changeCheckBox,
      changeOpacity,
      ...toRefs(state)
    }
  },
  components: {
    Code
  }
}
</script>
<style lang="scss" scoped>
@import '../../css/main.scss';
.select {
  margin-top: 20px;
}
</style>
